package com.azt.utils;

import com.xiaoleilu.hutool.util.CollectionUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.enums.EnumUtils;
import org.apache.commons.lang.enums.ValuedEnum;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by shangwq on 2016/5/21.
 */
public class CommonUtil {
	
	
	public static final String APPLIFIELD = "applifield";//应用领域数据字典父code
	
	public static final String BANKS = "banks"; //银行数据字典父code

    public static final String PUR_ASSET_TYPE = "purAssType";//采购商资质类型

    public static final String PRO_ASSET_TYPE = "proAssType";//采购商资质类型

	public static final List<String> specialArea = Arrays.asList("台湾省" , "香港特别行政区" , "澳门特别行政区");
	
	public static final String DEFUALT_USER_PASSWORD="123456";//默认用户密码
	
	public static final String DEFUALT_USER_ROLENAME="分公司管理员";//默认用户角色是分公司管理员
	
	public static final String MASTER_WEBSITE_URL="http://www.azt365.com";//现网：https://www.azt365.com

    /**
     * 分割List
     *
     * @param list 待分割的list
     * @param pageSize    每段list的大小
     * @return List<<List<T>>
     */
    public static <T> List<List<T>> splitList(List<T> list, int pageSize) {
        List<List<T>> listArray = new ArrayList<List<T>>();// 创建list数组,用来保存分割后的list
        if(CollectionUtil.isNotEmpty(list)) {
            int listSize = list.size(); // list的大小
            int page = (listSize + (pageSize - 1)) / pageSize;// 页数
            for (int i = 0; i < page; i++) { // 按照数组大小遍历
                List<T> subList = new ArrayList<T>(); // 数组每一位放入一个分割后的list
                for (int j = 0; j < listSize; j++) {// 遍历待分割的list
                    int pageIndex = ((j + 1) + (pageSize - 1)) / pageSize;// 当前记录的页码(第几页)
                    if (pageIndex == (i + 1)) {// 当前记录的页码等于要放入的页码时
                        subList.add(list.get(j)); // 放入list中的元素到分割后的list(subList)
                    }
                    if ((j + 1) == ((j + 1) * pageSize)) {// 当放满一页时退出当前循环
                        break;
                    }
                }
                listArray.add(subList);// 将分割后的list放入对应的数组的位中
            }
        }
        return listArray;
    }

    /**
     * 发送文本。使用UTF-8编码。
     */
    public static void renderText(HttpServletResponse response, String text) {
        render(response, "text/plain;charset=UTF-8", text);
    }

    /**
     * 发送json。使用UTF-8编码。
     */
    public static void renderJson(HttpServletResponse response, String text) {
        render(response, "application/json;charset=UTF-8", text);
    }

    /**
     * 发送xml。使用UTF-8编码。
     */
    public static void renderXml(HttpServletResponse response, String text) {
        render(response, "text/xml;charset=UTF-8", text);
    }

    /**
     * 发送内容。使用UTF-8编码。
     */
    public static void render(HttpServletResponse response, String contentType, String text) {
        response.setContentType(contentType);
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            writer.write(text);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(writer);
        }
    }

    public static Map getParameterMap(HttpServletRequest request) {
        // 参数Map
        Map properties = request.getParameterMap();
        // 返回值Map
        Map returnMap = new HashMap();
        Iterator entries = properties.entrySet().iterator();
        Map.Entry entry;
        String name = "";
        String value = "";
        while (entries.hasNext()) {
            entry = (Map.Entry) entries.next();
            name = (String) entry.getKey();
            Object valueObj = entry.getValue();
            if(null == valueObj){
                value = "";
            }else if(valueObj instanceof String[]){
                String[] values = (String[])valueObj;
                for(int i=0;i<values.length;i++){
                    value = values[i] + ",";
                }
                if(value.endsWith(",")) {
                    value = value.substring(0, value.length() - 1);
                }
            }else{
                value = valueObj.toString();
            }
            returnMap.put(name, value);
        }
        return returnMap;
    }

    public static int safeToInt(Object obj, int defaultValue) {
        int r = defaultValue;
        if (obj != null) {
            try {
                r = Integer.parseInt(String.valueOf(obj));
            } catch (Exception ex) {
            }
        }
        return r;
    }

    public static Integer safeToInteger(Object obj, Integer defaultValue) {
        Integer r = defaultValue;
        if (obj != null) {
            try {
                r = Integer.valueOf(String.valueOf(obj));
            } catch (Exception ex) {
            }
        }
        return r;
    }

    public static Integer safeToInteger(Object obj) {
        return safeToInteger(obj, null);
    }

    public static String safeToString(Object obj, String defaultValue) {
        String r = defaultValue;
        if (obj != null) {
            try {
                r = String.valueOf(obj);
            } catch (Exception ex) {}
        }
        return r;
    }

    public static String safeToString(Object obj) {
        return safeToString(obj, null);
    }

    public static Double safeToDouble(Object obj, Double defaultValue) {
        Double r = defaultValue;
        if (obj != null) {
            try {
                r = Double.valueOf(String.valueOf(obj));
            } catch (Exception ex) {
            }
        }
        return r;
    }

    public static Double safeToDouble(Object obj) {
        return safeToDouble(obj, null);
    }

    public static Boolean safeToBoolean(Object obj, Boolean defaultValue) {
        Boolean r = defaultValue;
        if (obj != null) {
            try {
                r = Boolean.valueOf(String.valueOf(obj));
            } catch (Exception ex) {
            }
        }
        return r;
    }

    public static boolean safeToBool(Object obj, boolean defaultValue) {
        boolean r = defaultValue;
        if (obj != null) {
            try {
                r = Boolean.parseBoolean(String.valueOf(obj));
            } catch (Exception ex) {
            }
        }
        return r;
    }

    public static Date safeToDate(Object obj, String format) {
        Date date = null;
        try {
            date = new SimpleDateFormat(format).parse(safeToString(obj, null));
        } catch (Exception e) {}
        return date;
    }

    public static String formatDate(Date date, String format) {
        String str = null;
        try {
            str = new SimpleDateFormat(format).format(date);
        } catch (Exception e) {}
        return str;
    }

    public static int getPageCount(int count, int size) {
        return count % size == 0 ? count / size : count / size + 1;
    }

    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
            InetAddress inet = null;
            try { // 根据网卡取本机配置的IP
                inet = InetAddress.getLocalHost();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            ip = inet.getHostAddress();
        }
        // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ip != null && ip.length() > 15) {
            if (ip.indexOf(",") > 0) {
                ip = ip.substring(0, ip.indexOf(","));
            }
        }
        return ip;
    }

    /**
     * 判断是否是ajax请求
     */
    public static boolean isAjax(HttpServletRequest request) {
    	String header = request.getHeader("X-Requested-With");
        return "XMLHttpRequest".equalsIgnoreCase(header);
    }

    /**
     * 获取之前请求的url，方便登录之后返回，只对非Ajax的GET请求有效
     * */
    public static String getPreUrl(HttpServletRequest request) {
        String url = "";
        if (!isAjax(request) && request.getMethod().equals("GET")) {
            StringBuilder redirect = new StringBuilder();
            redirect.append(request.getRequestURL().toString());
            String queryParams = StringUtils.trimToEmpty(request.getQueryString());
            if(StringUtils.isNotBlank(queryParams)){
                redirect.append("?").append(queryParams);
            }
            try {
                url += URLEncoder.encode(redirect.toString(), "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return url;
    }

    /**
     * 获取登录的url
     * */
    public static String getLoginUrl(HttpServletRequest request) {
        String url = "/user/login";
        String preUrl = getPreUrl(request);
        if(StringUtils.isNotBlank(preUrl)) {
            try {
                url += "?redirect=" + URLEncoder.encode(preUrl, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return url;
    }

    /**
     * 未授权处理：如果是非ajax的get请求，跳转回登录页面，如是ajax请求，返回401状态码
     * */
    public static void redirectToLogin(HttpServletRequest request, HttpServletResponse response) {
        if(isAjax(request)) {
            //ajax请求的话则401状态返回错误码
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            CommonUtil.renderJson(response, "401 Unauthorized");
        } else {
            String loginUrl = getLoginUrl(request);
            try {
                response.sendRedirect(loginUrl);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static Map getEnumMap(Class enumClass) {
        Map map = new LinkedHashMap();
        List<ValuedEnum> list = EnumUtils.getEnumList(enumClass);
        for(ValuedEnum valuedEnum : list) {
            map.put(valuedEnum.getValue() + "", valuedEnum.getName());
        }
        return map;
    }

    /**
     * 生成订单号[生成规则：yyMMddHHmmssSSS + 随机3位数字]
     * */
    public static String genOrderNumber() {
        return formatDate(new Date(), "yyMMddHHmmssSSS") + RandomStringUtils.randomNumeric(3);
    }

    public static String genPayNumber(String orderNumber, int batch) {
        return orderNumber + (batch < 10 ? "" + batch : batch) +  RandomStringUtils.randomNumeric(4);
    }

    /**
     * 生成分公司名称
     * */
    public static String branchCompanyName(String CompanyName,String branchName){
    	StringBuffer sb=new StringBuffer();
    	sb.append(CompanyName).append(branchName);
    	return sb.toString();
    }

    /**
     * 数字转汉字，如1 -> 一 (只能处理1~99之间的数)
     * */
    public static String num2CN(int num) {
        try {
            String[] array = {"一", "二", "三", "四", "五", "六", "七", "八", "九"};

            // 1
            if (num <= 9) {
                return array[num - 1];
            } else {
                //11
                String str = num + "";
                int num_1 = CommonUtil.safeToInteger(str.charAt(0));
                int num_2 = CommonUtil.safeToInteger(str.charAt(1));
                return (num_1 > 1 ? array[num_1 - 1] : "") + "十" + (num_2 > 0 ? array[num_2 - 1] : "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 截取字符,超出部分显示...
     * */
    public static String getSimpleStr(String str, int maxLength) {
        if(StrUtil.isNotBlank(str) && str.length() > maxLength) {
            return str.substring(0, maxLength) + "...";
        }
        return str;
    }

    public static String getHiddenStr(String str, int length) {
        String hc = "";
        if(StrUtil.isNotBlank(str)) {
            if (str.length() > length) {
                hc = "*****" + str.substring(length);
            } else {
                for (int i = 0; i < str.length(); i++) {
                    hc += "*";
                }
            }
        }
        return hc;
    }

    /**
     * 重置sessionid，原session中的数据自动转存到新session中<br>
     * 登录前的请求一般都是http的，http是不安全的，假设用户登录前的JSESSIONID被人取得，
     * 如果登录后不变更JSESSIONID的话，即使登录请求是https的，该用户仍然会被他人冒充。
     */
    public static void resetSessionId(HttpServletRequest request) {
        HttpSession oldSession = request.getSession(false);
        if(oldSession != null && !oldSession.isNew()) {
            //首先将原session中的数据转移至一临时map中
            Map<String, Object> tempMap = new HashMap();
            Enumeration<String> sessionNames = oldSession.getAttributeNames();
            while (sessionNames.hasMoreElements()) {
                String sessionName = sessionNames.nextElement();
                tempMap.put(sessionName, oldSession.getAttribute(sessionName));
            }

            //注销原session，为的是重置sessionId
            oldSession.invalidate();

            //将临时map中的数据转移至新session
            HttpSession newSession = request.getSession(true);
            for (Map.Entry<String, Object> entry : tempMap.entrySet()) {
                newSession.setAttribute(entry.getKey(), entry.getValue());
            }
        }
    }

    public static String toUtf8String(String s) {

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c >= 0 && c <= 255) {
                sb.append(c);
            } else {
                byte[] b;
                try {
                    b = Character.toString(c).getBytes("utf-8");
                } catch (Exception ex) {
                    b = new byte[0];
                }
                for (int j = 0; j < b.length; j++) {
                    int k = b[j];
                    if (k < 0)
                        k += 256;
                    sb.append("%" + Integer.toHexString(k).toUpperCase());
                }
            }
        }
        return sb.toString();
    }

    /**
     * 根据不同浏览器将文件名中的汉字转为UTF8编码的串,以便下载时能正确显示另存的文件名.
     *
     * @param s
     *            原文件名
     * @return 重新编码后的文件名
     */
    public static String toUtf8String(String agent, String s) {
        try {
            boolean isFireFox = (agent != null && agent.toLowerCase().indexOf("firefox") != -1);
            boolean isSafari = (agent != null && agent.toLowerCase().indexOf("safari") != -1);
            if (isFireFox || isSafari) {
                s = new String(s.getBytes("UTF-8"), "ISO8859-1");
            } else {
                s = toUtf8String(s);
                if ((agent != null && agent.indexOf("MSIE") != -1)) {
                    // see http://support.microsoft.com/default.aspx?kbid=816868
                    if (s.length() > 150) {
                        // 根据request的locale 得出可能的编码
                        s = new String(s.getBytes("UTF-8"), "ISO8859-1");
                    }
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return s;
    }


    /**
     * 对double数据进行取精度.
     * <p>
     * For example: <br>
     * double value = 100.345678; <br>
     * double ret = round(value,4,BigDecimal.ROUND_HALF_UP); <br>
     * ret为100.3457 <br>
     *
     * @param value
     *            double数据.
     * @param scale
     *            精度位数(保留的小数位数).
     * @param roundingMode
     *            精度取值方式.
     * @return 精度计算后的数据.
     */
    public static double round(double value, int scale, int roundingMode) {
        BigDecimal bd = new BigDecimal(value);
        bd = bd.setScale(scale, roundingMode);
        double d = bd.doubleValue();
        bd = null;
        return d;
    }
}